#'
#' @TODO 解压.gz文件到当前目录
#' @title 解压.gz文件到当前目录
#' @description 解压.gz文件到当前目录
#' @param file gz文件路径
#' @param args 参数设置，参考`gzip --help`
#' @usage ungz(./dir1/dir2/file.gz)
#' @export
#' @author *WYK*
ungz <- \(file_path = NULL, args = "dk"){
    stopifnot(file.exists(file_path))
    system(stringr::str_glue("gzip -{args} {file_path}"))
    return()
}


#'
#' @TODO ggsave升级版本
#' @title ggsave升级版本
#' @description 如果文件路径不存在则自动创建
#' @param filename 同`ggolot2::ggsave`，但是支持`str_glue`中用法，例如 "figure_{x}.pdf"
#' @param plot 同`ggolot2::ggsave`
#' @param width 同`ggolot2::ggsave`
#' @param height 同`ggolot2::ggsave`
#' @param ... 参数设置，参考`ggolot2::ggsave`
#' @export
#' @author *WYK*
ggsave3 <- \(filename = NULL, plot = NULL, width = NA, height = NA, ...){
    fn <- stringr::str_glue(filename)

    if (...length() > 0) {
        l <- c("filename" = fn, "plot" = plot, "width" = width, "height" = height, list(...))
    } else {
        l <- list("filename" = fn, "plot" = plot, "width" = width, "height" = height)
    }

    if (!dir.exists(dirname(fn))) {
        dir.create(dirname(fn), recursive = T)
        cli::cli_warn(paste0("dir {.path {dirname(fn)}} is automatically created."))
    }

    do.call(ggplot2::ggsave, args = l)
}



#'
#' @TODO write_tsv升级版本
#' @title write_tsv升级版本
#' @description 如果文件路径不存在则自动创建
#' @param file 同`readr::write_tsv`，但是支持`str_glue`中用法，例如 "figure_{x}.pdf"
#' @param x 同`readr::write_tsv`
#' @param ... 参数设置，参考`readr::write_tsv`
#' @export
#' @author *WYK*
write_tsv2 <- \(x = NULL, file = NULL, ...){
    fn <- stringr::str_glue(file)
    if (...length() > 0) {
        l <- c("file" = fn, "x" = x, list(...))
    } else {
        l <- list("file" = fn, "x" = x)
    }

    if (!dir.exists(dirname(fn))) {
        dir.create(dirname(fn), recursive = T)
        cli::cli_warn(paste0("dir {.path {dirname(fn)}} is automatically created."))
    }

    do.call(readr::write_tsv, args = l)
}


#'
#' @TODO write_tsv升级版本
#' @title write_tsv升级版本
#' @description 如果文件路径不存在则自动创建
#' @param file 同`saveRDS`，但是支持`str_glue`中用法，例如 "obj_{x}.rds"
#' @param object 同`saveRDS`
#' @param ... 参数设置，参考`saveRDS`
#' @export
#' @author *WYK*
saveRDS2 <- \(object, file = "", ...){
    fn <- stringr::str_glue(file)
    
    if (...length() > 0) {
        l <- c("object" = object, "file" = fn, list(...))
    } else {
        l <- list("object" = object, "file" = fn)
    }

    if (!dir.exists(dirname(fn))) {
        dir.create(dirname(fn), recursive = T)
        cli::cli_warn(paste0("dir {.path {dirname(fn)}} is automatically created."))
    }

    do.call(base::saveRDS, args = l)
}


#' @title 格式化p值
#' @description 格式化p值
#' @details 
#' @param p 数字向量，计算的p值,显著性标记默认小于0.01为**，0.01到0.05为*，大于0.05为空白
#' @export
#' @return 返回一个tibble，格式化以后的p值
#' @examples
#' @author *WYK*
#'
formatp <- function(p) {
    stopifnot(!class(p) %in% c("character", "list"))
    p_sig <- cut(p, c(0, .01, .05, Inf), c("**", "*", ""), include.lowest = TRUE)

    p_chr = rep('< .01',length(p))
    p_chr[p > .01] <- paste0("= ",round(p[p > .01],2))

    dplyr::tibble(p, p_sig, p_chr)
}



convert <- function(x, ...) {
    UseMethod("convert")
}

convert.Seurat <- function(x, od = "./", prefix = "nk", ...) {
    stopifnot("Seurat" %in% class(x))
    Sys.setenv(HDF5_USE_FILE_LOCKING = "FALSE")

    SeuratDisk::SaveH5Seurat(x, filename = str_glue("{od}/{prefix}.h5Seurat"))
    SeuratDisk::Convert(str_glue("{od}/{prefix}.h5Seurat"), dest = "h5ad")
    file.remove(str_glue("{od}/{prefix}.h5Seurat"))
}




# 定义函数来删除空行和注释行
clean_r_file <- function(input_file, output_file) {

  print(input_file)
  # 读取文件内容
  lines <- read_lines(input_file)
  
  # 过滤掉空行和注释行
  cleaned_lines <- lines[!grepl("^\\s*$|^\\s*#", lines)]
  
  # 将结果写回到新的文件中
  write_lines(cleaned_lines, output_file)
}


# 根据函数名称来找找到函数的全部信息
get_function <- function(x) {
  fun_name = as.character(match.call()$x)
  c(str_glue("{fun_name} = "),deparse(x))
}




#'
#' @title 检查文件路径的文件夹是否存在
#' @param x 文件路径
#' @return x
#'
file_dir_check <- check_file_dir <- \(x = NULL){
  dir.create(dirname(str_glue(x)), showWarnings = F, recursive = T)
  return(str_glue(x))
}
